#include <iostream>
#include <vector>
#include <mutex>
#include "thread.hpp"
#include "lockguard.hpp"

using namespace ThreadModule;
using namespace std;

class ThreadData
{
public:
    ThreadData(int &tickets, const string &name, pthread_mutex_t *mutex)
        : _tickets(tickets), _name(name), _total(0), _mutex(mutex)
    {
    }
    ~ThreadData()
    {
    }

public:
    int &_tickets;
    string _name;
    int _total;
    pthread_mutex_t *_mutex;
};

int g_tickets = 10000;

void route(ThreadData *td)
{
    while (true)
    {

        // LockGuard guard(&td->_mutex);
        pthread_mutex_lock(td->_mutex);

        if (td->_tickets > 0)
        {
            usleep(1000);
            printf("%s running,get tickets:%d\n", td->_name.c_str(), td->_tickets);
            td->_tickets--;
            td->_total++;
            pthread_mutex_unlock(td->_mutex);
        }
        else
        {
            pthread_mutex_unlock(td->_mutex);
            break;
        }
    }
}

const int num = 4;
int main()
{
    pthread_mutex_t mutex;
    // mutex mutex;
    pthread_mutex_init(&mutex, nullptr);
    vector<Thread<ThreadData *>> threads;
    vector<ThreadData *> datas;

    for (int i = 0; i < num; i++)
    {
        string name = "thread-" + to_string(i + 1);
        ThreadData *td = new ThreadData(g_tickets, name, &mutex);
        // ThreadData td(g_tickets,name,mutex);
        threads.emplace_back(route, td, name);
        datas.emplace_back(td);
    }
    for (auto &thread : threads)
    {
        thread.start();
    }
    for (auto &thread : threads)
    {
        thread.join();
    }
    sleep(1);
    for (auto data : datas)
    {
        cout << data->_name << ":" << data->_total << endl;
        delete data;
    }
    return 0;
}
